# Contributing Guidelines

[[toc]]

## Виды участия в роадмапе
  - 💡 [Создавайте issue](https://github.com/tlbootcamp/tlroadmap/issues/new), если вы видите, что мы не охватили какую-то область ответственности тимлида, где-то ошиблись или у вас просто есть отличная идея для обсуждения.
  - 🚫 [Присылайте Pull Request](https://github.com/tlbootcamp/tlroadmap/compare) с исправлением фактических ошибок.
  - 📚 [Дорабатывайте базу знаний](https://github.com/tlbootcamp/tlroadmap/issues?q=is%3Aissue+is%3Aopen+label%3Aknowledge-base) – как новые ветки, так и отдельные секции в уже готовых (например, "Как прокачать", "Примеры поведения" или "Список литературы").

Если вы не знаете, чем конкретно хотите заняться, то можете пробежаться по нашим Issues – их очень много на любой вкус.

Если вы готовы взять в работу описание одной из компетенций, то пройдитесь по нашему чек-листу:
1. Проверьте, что на [доске проекта](https://github.com/tlbootcamp/tlroadmap/projects/1) в колонке "In progress" эта задача отсутствует, иначе вы рискуете проделать двойную работу.
1. Найдите соответствующий тикет [с лейблом `knowledge-base`](https://github.com/tlbootcamp/tlroadmap/issues?q=is%3Aissue+is%3Aopen+label%3Aknowledge-base) в Issues и заассайньте его на себя. На доске проекта передвиньте в статус "In progress".
1. Прочитайте главу [Как изменить или добавить новое в роадмап](#как-изменить-или-добавить-новое-в-роадмап) ниже.
1. [Пришлите PR](https://github.com/tlbootcamp/tlroadmap/compare).

### Процесс принятия изменений
В репозитории два мейнтейнера: [etolstoy](https://github.com/etolstoy) и [DevAlloy](https://github.com/DevAlloy)

1. Для мелкофиксов достаточно апрува одного из мейнтейнеров.
1. Для более сложных PR требуется апрув обоих мейнтейнеров.

Мы стараемся разбирать PR и issue в течение 1-3 дней. Максимальный срок разбора – 7 дней.


## Как изменить или добавить новое в роадмап

### Что такое роадмап
Наш роадмап — это такой граф, состоящий из статей о компетенциях и веток, объединяющих такие статьи в древовидную структуру.

Это дерево представлено в виде вложенных папок и файлов с расширением `.md`. Каждая папка — это ветка от родительской папки, каждый файл — это информация о ветке или описание компетенции.

Например, мы хотим показать на роадмапе, что компетенция "Дача и получение обратной связи" лежит в ветке "Коммуникации", а она в ветке "Personal Skills". Структура папок и файлов тогда будет выглядеть вот так:
```
├── tlroadmap
│   ├── personal-skills
│   │   ├── communications
│   │   │   ├── feedback
│   │   │   │   └── ru.md
```

::: tip
Иногда мы будем называть файлы с описаниями компетенций "листочками" дерева
:::

### Какой формат у файлов с описаниями компетенций
В качестве формата мы используем Markdown. Это простой, человекочитаемый и легковесный язык разметки, с основными функциями которого можно познакомиться [здесь](https://www.markdownguide.org/basic-syntax/).

Название у файлов соответствуют двухбуквенному имени локали + `.md`, например `ru.md`, `zh.md`. Это позволяет нам составлять локализованные версии роадмапа.

Мы стараемся содержать базу знаний в едином формате (одинаковая система заголовков и изложения), который можно подсмотреть в нашем [шаблоне](https://github.com/tlbootcamp/tlroadmap/blob/master/tlroadmap/.template/ru.md).

В начале каждого файла _может_ идти специальный блок с мета-информацией в формате [Frontmatter](https://jekyllrb.com/docs/front-matter/), которая используется при сборке. Она может выглядеть вот так:
```
---
title: Моя новая ветка
color: blue
author: Dima Boger
---
```

### Как работает сайт
Мы собираем сайт и артефакты автоматически с помощью [VuePress](https://vuepress.vuejs.org/) и пачки специальных утилит и плагинов, которые извлекают нужную информацию из дерева папок и файлов с описанием компетенций.

Во время описания новых веток иногда хочется посмотреть как они будут выглядеть на сайте: для этого используйте команду `yarn site:dev`, она запустит локальную версию сайта. Перед этим придётся поставить [node](https://nodejs.org/en/download/), [yarn](https://classic.yarnpkg.com/en/docs/install/) и зависимости проекта через `yarn install`.

Обратите внимание, что локальная версия сайта не содержит .png, .svg и .mm файлов с роадмапом, потому что для их генерации требуются дополнительные зависимости (python, java, ...).

Впрочем, для каждого PR с изменениями в GitHub мы генерируем полную версию сайта, которая прикрепляется к PR в виде блока "Deployments"

### Как создать новое описание компетенции
Сначала нужно найти место в иерархии, в которое вы хотите добавить новую компетенцию. В качестве примера рассмотрим компетенцию "Continuous Integration".

Мы хотим расположить её как-то так Роли → Technical Lead → Автоматизация цикла разработки -> Continuous Integration, что соответствует пути tlroadmap/roles/tech-lead/automation

Создайте там новую папку с коротким и понятным названием на английском. Используйте нижний регистр букв, а пробелы замените на дефисы `-`. В нашем случае — `ci` или `continuous-integration`. У вас получится структура `tlroadmap/roles/tech-lead/automation/continuous-integration`

Теперь нужно создать файл с контентом. Для этого используйте наш шаблон для описаний: скопируйте файл [.template/ru.md](https://github.com/tlbootcamp/tlroadmap/blob/master/tlroadmap/.template/ru.md) в `tlroadmap/roles/tech-lead/automation/continuous-integration/ru.md` и заполняйте его, согласно инструкции внутри.

### Как сделать новую ветку
Большинство веток (не путайте с листочками) не содержат подробного описания и служат для логической группировки компетенций.

Если вы хотите добавить или переместить компетенцию, которой не хватает своей, отдельной, ветки, то воспользуйтесь следующей инструкцией:
1. Создайте новую папку с коротким и понятным названием на английском. Используйте нижний регистр букв, а пробелы замените на дефисы `-`. Например новая ветка "Менеджер проекта" может выглядеть как папка `project-manager`.
1. Убедитесь, что папка лежит в нужном месте в иерархии веток. Для менеджера проектов это ветка "Роли": `tlroadmap/roles/project-manager`.
1. В этой папке создайте файл `ru.md` — он понадобится, чтобы хранить мета-информацию о ветке (например, перевод её названия на русский).
1. Добавьте в `ru.md` Frontmatter-разметку с `title`:
```
---
title: Менеджер проекта
---
```

### Перекрёстные ссылки
Иногда есть необходимость оставить в описании компетенции ссылку на другую, смежную компетенцию. Для этого можно использовать перекрёстные ссылки. Из-за особенностей генерации локализованной версии сайта, пути на сайте немного отличаются от путей в файловой системе, поэтому нужно быть аккуратным.

Например, при необходимости оставить ссылку на компетенцию "Работа с привычками" (`tlroadmap/personal-skills/self-development/habits/ru.md`) нужно использовать  путь, который начинается с самой верхней папки (`roles` или `personal-skills`), без `ru.md`, но с `.html`: `[Работа с привычками](/personal-skills/self-development/habits.html)`

### Вставка изображения
Для того чтобы вставить изображение используйте стандартный markdown-синтаксис: `![Image Description](./relative-path-to-image.png)`

Не ссылайтесь на изображения на других сайтах. Положите изображение в папку рядом с файлом с описанием компетенции и используйте относительный путь как в примере выше. Убедитесь, что лицензия изображения позволяет его использовать в нашем проекте (т.е. совместима с CC-BY-SA 4.0)

### Проверка орфографии и формата файлов
Мы хотим автоматизировать всё что можно автоматизировать, поэтому используем богатый набор утилит:
  - проверяем орфографию с помощью [yaspeller](https://github.com/hcodes/yaspeller): `npx yaspeller --config .yaspellerrc.json .`
  - восстанавливаем пропущенные буквы ё c помощью [eyo](https://www.npmjs.com/package/eyo): `npx eyo --only-safe --in-place "**/*.md"`
  - проверяем формат файлов на соответствие [Editor Config](https://editorconfig.org/) с помощью [eclint](https://www.npmjs.com/package/eclint): `npx eclint check .`
  - проверяем что все ссылки на сайте ведут на доступные страницы с помощью [HTMLProofer](https://github.com/gjtorikian/html-proofer)
  - проверяем структуру, именование папок, мета-информацию в файлах через свою утилиту: `bash tools/check_directory_tree.sh`

Все эти проверки являются необходимым условием для принятия всех новых изменений и запускаются автоматически при создании PR. Локально прогонять их не требуется, главное – следите за результатами проверок на CI и исправляйте найденные проблемы.

### Как залить свои изменения
Всё как всегда: перечитайте CONTRIBUTING.md, сделайте fork репозитория, внесите изменения, запушьте их и создайте PR из вашей ветки в основной репозиторий.

Дальше произойдёт следующее:
  - запустится кучка проверок, и все найденные проблемы будут автоматически добавлены к строчкам текста из вашего PR
  - развернётся специальная версия сайта с вашими правками и привяжется к PR
  - если автоматические проверки в PR светят зелёным, то в течение нескольких дней ваши изменения отсмотрят мейнтейнеры

## FAQ
### У вас тут проверка орфографии работает неправильно!
Для проверки орфографии мы используем `yaspeller`, и иногда он не поспевает за новшествами языка, не понимает красивый способ словообразования и не знаком с IT сленгом. Если слово корректно, но `yaspeller` думает, что это ошибка – добавьте в файл `.yaspellerrc.json` в массив `dictionary`.

Если это паттерн – например, имена в названиях книг – имеет смысл добавить regexp в поле `ignoreText`.

Блоки ссылок можно завернуть в специальные markdown-комментарии:
```
<!-- yaspeller ignore:start -->
ссылка
ссылка
<!-- yaspeller ignore:end -->
```

### Я создал PR и мне выдало ошибку на "Check links"
К сожалению, мы ещё не научились прикреплять результат работы HTMLProofer прямо к файлам, поэтому придётся прочитать результат проверки.

Возможные проблемы и их решения:

#### Утилита подсветила проблему с одной из _внутренних_ ссылок среди ваших изменений
Такое бывает, если вы упоминаете в своём описании компетенций другую ветку. Обратите внимание, что пути на сайте не всегда соответствуют путям в файловой структуре. Подробнее об этом можно почитать в разделе "Перекрёстные ссылки". Простой способ узнать правильную ссылку — зайти на сгенерированную версию сайта и найти нужную страницу. Если вы не хотите запускать веб-сервер, то к каждому PR мы прикрепляем тестовую версию сайта в блок `Deployments`.

#### Утилита подсветила проблему с одной из _внешних_ ссылок среди ваших изменений
Если по прямому клику по ссылке у вас всё открывается, а утилита утверждает, что сайт недоступен, то скорее всего сайт борется с роботами и банит запросы от нашей утилиты или утилита не понимает его ответ. Обычно это ошибка 503 или `got a time out (response code 0)`. Варианта решения два:
  - Если этот сайт по вашим ощущениям может использоваться во многих других статьях (например "Консультант" или "Википедия"), то его нужно добавить в общий список исключений `--ignore-urls` в формате регулярного выражения.
  - Если этот сайт специфичен для этой компетенции, то замените markdown-ссылку на html-ссылку с атрибутом `data-proofer-ignore`
  Например ссылка `[Avito Tech Radar](https://techaradar.avito.ru)` превратится в `<a href="https://techradar.avito.ru/" data-proofer-ignore>Avito Tech Radar</a>`.

Если по прямому клику статья не открывается, значит статью удалили, закрыли к ней доступ или сайт сменил свой адрес.

Бывает такое, что ссылка вчера открывалась, а сегодня как раз во время отправки PR сайт ушёл на тех.обслуживание, а сейчас снова работает. Если сайт обещает так больше не делать, то нужно просто перезапустить упавшую проверку в Github Actions. Если сайт работает нестабильно, то это повод задуматься о включении такой ссылки как источника.

#### Сломалась ссылка, но в другом файле, который вы не редактировали
Такое бывает, когда ссылка устаревает или сайт меняет механизм обработки запросов. Если ссылка выдаёт что-то вроде 404 — то это повод её удалить или заменить на другую. Обсудите с мейнтейнерами, возможно они возьмут эту задачу на себя, и вам нужно будет просто подтянуть их изменения.


### Зачем каждый раз создавать ru.md, если язык сейчас всё равно один?
Мы подготовили платформу сайта к поддержке мультиязычности и в планах у нас есть перевод роадмапа на английский.

### Я запустил локально сайт, но ссылки на картинки с роадмапом всё ещё ведут на главный сайт / не открываются
В локальной версии сайта бинарные артефакты не генерируются (но вы можете сгенерировать их при желании)

Роадмап изначально представлял из себя plain-папку с .md файлами и .mm файл, который нужно было вручную редактировать с каждым новым релизом. Постепенно мы снижали (и продолжаем снижать) нагрузку с контрибьюторов и мейнтейнеров, пряча всю генерацию за автоматические утилиты. К сожалению, большинство этих утилит требуют разнообразное окружение, и мы уже собрали бинго из js, java и python, и, похоже, не собираемся останавливаться.

Из хороших новостей — к каждому PR мы прикрепляем полноценную версию сайта, которую можно посмотреть на вкладке "Deployments". Если вас это не устраивает, и всё ещё хочется иметь бинарные артефакты локально, то изучите папку `.github/workflows`

### Как добавить новую локализацию?
Создайте новый issue и давайте обсудим! С технической стороны всё просто: нужно добавить новую локаль в `.vuepress/config.js`

### Как добавить компонент с логикой в .md файл?
В файлах роадмапа можно встретить расширение .md файлов с помощью полноценных Vue-компонентов (например `<Roadmap>`). Это работает потому что мы используем VuePress с [поддержкой Vue-компонентов](https://v1.vuepress.vuejs.org/guide/using-vue.html#using-vue-in-markdown).
